package cn.south.campus.common.utils;

import com.alibaba.fastjson2.JSON;
import org.springframework.util.CollectionUtils;

import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

public class HttpUtils {

    /**
     * get请求
     *
     * @param req    请求参数
     * @param urlStr 链接
     * @return 响应
     */
    public static String getReq(Map<String, Object> req, String urlStr) {
        if (!CollectionUtils.isEmpty(req)) {
            urlStr += "?";
            StringBuilder urlStrBuilder = new StringBuilder(urlStr);
            for (Map.Entry<String, Object> entry : req.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                urlStrBuilder.append(key).append("=").append(value).append("&");
            }
            urlStr = urlStrBuilder.toString();
            if (urlStr.endsWith("&")) {
                urlStr = urlStr.substring(0, urlStr.length() - 1);
            }
        }
        HttpURLConnection connection = null;
        ByteArrayOutputStream baos = null;
        try {
            URL url = new URL(urlStr);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            handlerHttps(connection);
            connection.connect();
            InputStream in = connection.getInputStream();
            int count = connection.getContentLength();//获取远程资源长度
            byte[] buffer = new byte[count];
            baos = new ByteArrayOutputStream();
            for (int len = 0; (len = in.read(buffer)) > 0; ) {
                baos.write(buffer, 0, len);
            }
            return baos.toString("utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * post请求
     *
     * @param req    请求参数
     * @param urlStr 链接
     * @return 响应
     */
    public static String postReq(Map<String, Object> req, String urlStr) {
        HttpURLConnection connection = null;
        ByteArrayOutputStream baos = null;
        try {
            URL url = new URL(urlStr);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            handlerHttps(connection);
            connection.connect();
            OutputStream outputStream = connection.getOutputStream();
            if (req != null) {
                outputStream.write(JSON.toJSONString(req).getBytes(StandardCharsets.UTF_8));
            }
            InputStream in = connection.getInputStream();
            baos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            for (int len = 0; (len = in.read(b)) > 0; ) {
                baos.write(b, 0, len);
            }
            return baos.toString("utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static String putReq(Map<String,Object> param, String urlStr) {
        HttpURLConnection connection = null;
        ByteArrayOutputStream baos = null;
        try {
            URL url = new URL(urlStr);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("PUT");
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            handlerHttps(connection);
            connection.connect();
            OutputStream outputStream = connection.getOutputStream();
            if (param != null) {
                outputStream.write(JSON.toJSONString(param).getBytes(StandardCharsets.UTF_8));
            }
            InputStream in = connection.getInputStream();
            baos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            for (int len = 0; (len = in.read(b)) > 0; ) {
                baos.write(b, 0, len);
            }
            return baos.toString("utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    private static void handlerHttps(HttpURLConnection connection) throws NoSuchAlgorithmException, KeyManagementException {
        if (connection instanceof HttpsURLConnection) {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            TrustManager[] tm = new TrustManager[]{new MyX509TrustManager()};
            sslContext.init(null, tm, new SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            ((HttpsURLConnection) connection).setSSLSocketFactory(ssf);
        }
    }

    private static class MyX509TrustManager implements X509TrustManager {
        private MyX509TrustManager() {
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}
